use crate::{
    ast::{types, SliceExpr, Type},
    error::{CompilerError, Result},
    llvm_backend::LLVMBackend,
};
use inkwell::{
    types::{BasicType, BasicTypeEnum},
    values::{BasicValueEnum, IntValue, PointerValue},
    AddressSpace,
};

impl<'ctx> LLVMBackend<'ctx> {
    /// Generate slice expression (slice literal)
    pub(in crate::llvm_backend) fn generate_slice_expression(
        &mut self,
        slice_expr: &SliceExpr,
    ) -> Result<BasicValueEnum<'ctx>> {
        // Get element type
        let element_llvm_type =
            self.nrc_type_to_llvm_type(&Some(slice_expr.element_type.clone()))?;

        // 处理count参数
        let (elements, length) = if let Some(count_expr) = &slice_expr.count {
            // 重复元素模式: []int32{0; count: 5}
            let count_value = self.generate_expression(count_expr)?;
            let mut count_int = count_value.into_int_value();

            // Convert to i64 if necessary
            if count_int.get_type() != self.context.i64_type() {
                count_int = self.builder.build_int_z_extend_or_bit_cast(
                    count_int,
                    self.context.i64_type(),
                    "count_i64",
                )?;
            }

            if slice_expr.elements.len() != 1 {
                return Err(CompilerError::internal(
                    "count requires exactly one element",
                ));
            }

            let element_value = self.generate_expression(&slice_expr.elements[0])?;
            (vec![element_value], count_int)
        } else {
            // 普通元素模式
            let mut element_values = Vec::new();
            for element in &slice_expr.elements {
                let mut element_value = self.generate_expression(element)?;

                // Convert the element value to match the slice element type if necessary
                if element_value.get_type() != element_llvm_type {
                    // Handle float truncation (f64 -> f32)
                    if element_value.is_float_value() && element_llvm_type.is_float_type() {
                        let float_val = element_value.into_float_value();
                        let target_float_type = element_llvm_type.into_float_type();
                        // Always truncate/extend to match target type
                        element_value = self
                            .builder
                            .build_float_cast(float_val, target_float_type, "float_cast")?
                            .into();
                    }
                    // Handle integer truncation/extension
                    else if element_value.is_int_value() && element_llvm_type.is_int_type() {
                        let int_val = element_value.into_int_value();
                        let target_int_type = element_llvm_type.into_int_type();
                        if int_val.get_type().get_bit_width() < target_int_type.get_bit_width() {
                            element_value = self
                                .builder
                                .build_int_z_extend(int_val, target_int_type, "int_ext")?
                                .into();
                        } else if int_val.get_type().get_bit_width()
                            > target_int_type.get_bit_width()
                        {
                            element_value = self
                                .builder
                                .build_int_truncate(int_val, target_int_type, "int_trunc")?
                                .into();
                        }
                    }
                }

                element_values.push(element_value);
            }
            let length = self
                .context
                .i64_type()
                .const_int(element_values.len() as u64, false);
            (element_values, length)
        };

        // 处理容量
        let capacity = if let Some(cap_expr) = &slice_expr.capacity {
            let cap_value = self.generate_expression(cap_expr)?;
            let mut cap_int = cap_value.into_int_value();

            // Convert to i64 if necessary
            if cap_int.get_type() != self.context.i64_type() {
                cap_int = self.builder.build_int_z_extend_or_bit_cast(
                    cap_int,
                    self.context.i64_type(),
                    "cap_i64",
                )?;
            }

            cap_int
        } else {
            length // 默认容量等于长度
        };

        // Allocate memory for the backing array using malloc
        // Calculate the size based on the element type
        let element_size = match &slice_expr.element_type {
            Type::Basic(basic_type) => {
                match basic_type {
                    types::BasicType::Int8 | types::BasicType::Uint8 | types::BasicType::Char => 1,
                    types::BasicType::Int16 | types::BasicType::Uint16 => 2,
                    types::BasicType::Int32
                    | types::BasicType::Uint32
                    | types::BasicType::Float32 => 4,
                    types::BasicType::Int
                    | types::BasicType::Int64
                    | types::BasicType::Uint
                    | types::BasicType::Uint64
                    | types::BasicType::Float64 => 8,
                    types::BasicType::Bool => 1,
                    _ => 8, // Default to 8 bytes for pointer types
                }
            }
            _ => 8, // Default size
        };

        let element_size_const = self.context.i64_type().const_int(element_size, false);
        let array_size_bytes =
            self.builder
                .build_int_mul(capacity, element_size_const, "array_size_bytes")?;

        let malloc_func = self.function_map.get("__malloc").unwrap();
        let malloc_call = self.builder.build_call(
            *malloc_func,
            &[array_size_bytes.into()],
            "slice_array_malloc",
        )?;
        let array_ptr_i8 = malloc_call
            .try_as_basic_value()
            .left()
            .unwrap()
            .into_pointer_value();

        // Cast i8* to element_type*
        let array_ptr = self
            .builder
            .build_bitcast(
                array_ptr_i8,
                element_llvm_type.ptr_type(AddressSpace::default()),
                "slice_array_ptr",
            )?
            .into_pointer_value();

        // 填充元素
        if slice_expr.count.is_some() {
            // 重复元素模式：用第一个元素填充所有位置
            let element_value = elements[0];
            self.fill_slice_with_value(array_ptr, element_llvm_type, element_value, length)?;
        } else {
            // 普通模式：逐个填充
            for (i, element_value) in elements.iter().enumerate() {
                let index_value = self.context.i64_type().const_int(i as u64, false);
                let element_ptr = unsafe {
                    self.builder.build_gep(
                        element_llvm_type,
                        array_ptr,
                        &[index_value],
                        &format!("slice_elem_{}_ptr", i),
                    )?
                };
                let _ = self.builder.build_store(element_ptr, *element_value);
            }
        }

        // Create slice struct: { ptr: *T, len: i64, cap: i64 }
        let ptr_type = element_llvm_type.ptr_type(AddressSpace::default());
        let len_type = self.context.i64_type();
        let cap_type = self.context.i64_type();
        let slice_struct_type = self
            .context
            .struct_type(&[ptr_type.into(), len_type.into(), cap_type.into()], false);

        // Allocate memory for the slice struct
        let slice_alloca = self
            .builder
            .build_alloca(slice_struct_type, "slice_alloca")?;

        // Store ptr field (index 0)
        let ptr_field_ptr = unsafe {
            self.builder.build_gep(
                slice_struct_type,
                slice_alloca,
                &[
                    self.context.i32_type().const_int(0, false),
                    self.context.i32_type().const_int(0, false),
                ],
                "slice_ptr_field",
            )?
        };
        let _ = self.builder.build_store(ptr_field_ptr, array_ptr);

        // Store len field (index 1)
        let len_field_ptr = unsafe {
            self.builder.build_gep(
                slice_struct_type,
                slice_alloca,
                &[
                    self.context.i32_type().const_int(0, false),
                    self.context.i32_type().const_int(1, false),
                ],
                "slice_len_field",
            )?
        };
        let len_value = length;
        let _ = self.builder.build_store(len_field_ptr, len_value);

        // Store cap field (index 2) - for literals, len == cap
        let cap_field_ptr = unsafe {
            self.builder.build_gep(
                slice_struct_type,
                slice_alloca,
                &[
                    self.context.i32_type().const_int(0, false),
                    self.context.i32_type().const_int(2, false),
                ],
                "slice_cap_field",
            )?
        };
        let cap_value = capacity;
        let _ = self.builder.build_store(cap_field_ptr, cap_value);

        // Load and return the complete slice struct
        let slice_value =
            self.builder
                .build_load(slice_struct_type, slice_alloca, "slice_value")?;
        Ok(slice_value)
    }

    fn fill_slice_with_value(
        &mut self,
        array_ptr: PointerValue<'ctx>,
        element_type: BasicTypeEnum<'ctx>,
        value: BasicValueEnum<'ctx>,
        count: IntValue<'ctx>,
    ) -> Result<()> {
        // 创建循环来填充重复值
        let current_func = self
            .current_function
            .ok_or_else(|| CompilerError::internal("No current function"))?;
        let loop_block = self.context.append_basic_block(current_func, "fill_loop");
        let body_block = self.context.append_basic_block(current_func, "fill_body");
        let end_block = self.context.append_basic_block(current_func, "fill_end");

        // 初始化循环变量
        let zero = self.context.i64_type().const_int(0, false);
        let one = self.context.i64_type().const_int(1, false);

        // Get the entry block before jumping
        let entry_block = self.builder.get_insert_block().unwrap();

        // 跳转到循环
        self.builder.build_unconditional_branch(loop_block)?;

        // 循环条件检查
        self.builder.position_at_end(loop_block);
        let i_phi = self.builder.build_phi(self.context.i64_type(), "i")?;
        i_phi.add_incoming(&[(&zero, entry_block)]);
        let i = i_phi.as_basic_value().into_int_value();

        let cond =
            self.builder
                .build_int_compare(inkwell::IntPredicate::ULT, i, count, "loop_cond")?;

        self.builder
            .build_conditional_branch(cond, body_block, end_block)?;

        // 循环体：填充元素
        self.builder.position_at_end(body_block);
        let element_ptr = unsafe {
            self.builder
                .build_gep(element_type, array_ptr, &[i], "element_ptr")?
        };
        self.builder.build_store(element_ptr, value)?;

        // 递增循环变量
        let i_next = self.builder.build_int_add(i, one, "i_next")?;
        i_phi.add_incoming(&[(&i_next, body_block)]);

        self.builder.build_unconditional_branch(loop_block)?;

        // 结束
        self.builder.position_at_end(end_block);
        Ok(())
    }
}
